unit Helpers;

interface

uses
  OmniXML, OmniXML_Types, FMX.Types, System.UITypes, System.Types;

type
  TTFontHelper = class helper for TFont
    procedure StoreToXML(Node: IXMLNode; Name: String);
    procedure RestoreFromXML(Node: IXMLNode; Name: String);
  end;

  TTPointFHelper = record helper for TPointF
    procedure StoreToXML(Node: IXMLNode; Name: String);
    procedure RestoreFromXML(Node: IXMLNode; Name: String);
  end;

function StoreProperty(Node: IXMLNode; Name: String; Value: OleVariant): IXMLNode;
function StoreSingleProperty(Node: IXMLNode; Name: String; Value: Single): IXMLNode;
function RestoreProperty(Node: IXMLNode; Name: String): OleVariant;
function RestoreSingleProperty(Node: IXMLNode; Name: String): Single;

function ToStr(Value: Single): String; overload;
function ToStr(Value: Extended): String; overload;
function ToStr(Value: Integer): String; overload;
function ToStr(Value: Pointer): String; overload;

function ToPointer(Value: XmlString): Pointer;

implementation

uses
  System.SysUtils;

type
  PFontStyles = ^TFontStyles;
  PInteger = ^Integer;

function ToPointer(Value: XmlString): Pointer;
begin
  result:=Pointer(StrToInt(Value));
end;

function ToStr(Value: Pointer): String;
begin
  result:=ToStr(Integer(Value));
end;

function ToStr(Value: Integer): String;
begin
  result:=IntToStr(Value);
end;

function ToStr(Value: Single): String;
var
  fs: TFormatSettings;
begin
  fs.DecimalSeparator:='.';
  fs.ThousandSeparator:=#0;
  result:=FloatToStr(Value, fs);
end;

function ToStr(Value: Extended): String; overload;
var
  fs: TFormatSettings;
begin
  fs.DecimalSeparator:='.';
  fs.ThousandSeparator:=#0;
  result:=FloatToStr(Value, fs);
end;

function FontStylesToInteger(const Value: TFontStyles): Integer;
begin
  result:=PInteger(@Value)^;
end;

function IntegerToFontStyles(const Value: Integer): TFontStyles;
begin
  result:=PFontStyles(@Value)^;
end;

function StoreProperty(Node: IXMLNode; Name: String; Value: OleVariant): IXMLNode;
begin
  result:=Node.AddChild(name);
  result.Text:=Value;
end;

function StoreSingleProperty(Node: IXMLNode; Name: String; Value: Single): IXMLNode;
var
  fs: TFormatSettings;
begin
  fs.DecimalSeparator:='.';
  fs.ThousandSeparator:=#0;
  result:=Node.AddChild(name);
  result.Text:=FloatToStr(Value, fs);
end;

function RestoreProperty(Node: IXMLNode; Name: String): OleVariant;
var
  item: IXMLNode;
begin
  item:=Node.FindNode(Name);
  result:=item.Text;
end;

function RestoreSingleProperty(Node: IXMLNode; Name: String): Single;
var
  item: IXMLNode;
  fs: TFormatSettings;
begin
  fs.DecimalSeparator:='.';
  fs.ThousandSeparator:=#0;
  item:=Node.FindNode(Name);
  result:=StrToFloat(item.Text, fs);
end;

{ TTFontHelper }

procedure TTFontHelper.RestoreFromXML(Node: IXMLNode; Name: String);
var
  item: IXMLNode;
begin
  item:=Node.FindNode(Name);
  Size:=RestoreProperty(item, 'Size');
  Style:=IntegerToFontStyles(RestoreProperty(item, 'Style'));
  Family:=RestoreProperty(item, 'Family');
end;

procedure TTFontHelper.StoreToXML(Node: IXMLNode; Name: String);
var
  item: IXMLNode;
begin
  item:=Node.AddChild(Name);
  item.Attributes['type']:='TFont';
  StoreProperty(item, 'Size', Self.Size);
  StoreProperty(item, 'Style', FontStylesToInteger(Self.Style));
  StoreProperty(item, 'Family', Self.Family);
end;

{ TTPointFHelper }

procedure TTPointFHelper.RestoreFromXML(Node: IXMLNode; Name: String);
var
  item: IXMLNode;
begin
  item:=Node.FindNode(Name);
  X:=RestoreSingleProperty(item, 'X');
  Y:=RestoreSingleProperty(item, 'Y');
end;

procedure TTPointFHelper.StoreToXML(Node: IXMLNode; Name: String);
var
  item: IXMLNode;
begin
  item:=Node.AddChild(Name);
  item.Attributes['type']:='TPointF';
  StoreSingleProperty(item, 'X', X);
  StoreSingleProperty(item, 'Y', Y);
end;

end.
